/**
 * Copyright 2009 Fabian Henniges, Henning Teek
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.chigs.web.auth;

import org.apache.wicket.authentication.panel.SignInPanel;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.RequiredTextField;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.request.target.basic.RedirectRequestTarget;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.util.value.ValueMap;

import com.googlecode.chigs.repository.UserService;
import com.googlecode.chigs.web.ChigsWebSession;
import com.googlecode.chigs.web.common.IconFactory;

/**
 * @author Henning Teek
 */
public class LoginPanel extends Panel {
	@SpringBean
	UserService userService;

	/** True if the panel should display a remember-me checkbox */
	private boolean includeRememberMe = true;

	/** Field for password. */
	private PasswordTextField password;

	/** True if the user should be remembered via form persistence (cookies) */
	private boolean rememberMe = false;

	/** Field for user name. */
	private TextField<String> email;
	
	public LoginPanel(final String id) {
		this(id, true);
	}

	public LoginPanel(final String id, final boolean includeRememberMe) {
		super(id);
		this.includeRememberMe = includeRememberMe;
		add(new SignInForm("login.form"));
	}

	/**
	 * Removes persisted form data for the signin panel (forget me)
	 */
	public final void forgetMe() {
		// Remove persisted user data. Search for child component
		// of type SignInForm and remove its related persistence values.
		getPage().removePersistedFormData(SignInPanel.SignInForm.class, true);
	}

	/**
	 * Convenience method to access the password.
	 * 
	 * @return The password
	 */
	public String getPassword() {
		return password.getInput();
	}

	/**
	 * Get model object of the rememberMe checkbox
	 * 
	 * @return True if user should be remembered in the future
	 */
	public boolean getRememberMe() {
		return rememberMe;
	}

	/**
	 * Convenience method to access the email.
	 * 
	 * @return The email
	 */
	public String getEmail()	{
		return email.getDefaultModelObjectAsString();
	}

	/**
	 * Convenience method set persistence for username and password.
	 * 
	 * @param enable whether the fields should be persistent
	 */
	public void setPersistent(final boolean enable)	{
		email.setPersistent(enable);
	}

	/**
	 * Set model object for rememberMe checkbox
	 * 
	 * @param rememberMe
	 */
	public void setRememberMe(final boolean rememberMe)	{
		this.rememberMe = rememberMe;
		setPersistent(rememberMe);
	}

	protected void onSignInFailed()	{
		// Try the component based localizer first. If not found try the
		// application localizer. Else use the default
		error(getLocalizer().getString("signInFailed", this, "Sign in failed"));
	}
	
	protected void onSignInSucceeded() {
		// If login has been called because the user was not yet
		// logged in, than continue to the original destination,
		// otherwise to the Home page
		if (!continueToOriginalDestination()) {
			setResponsePage(getApplication().getHomePage());
		}
	}

	public final class SignInForm extends Form<Void> {
		private final ValueMap properties = new ValueMap();

		public SignInForm(final String id) {
			super(id);

			// Attach textfield components that edit properties map
			// in lieu of a formal beans model
			add(email = new RequiredTextField<String>("email", new PropertyModel<String>(properties, "email"), String.class));
			add(password = new PasswordTextField("password", new PropertyModel<String>(properties, "password")));
			password.setType(String.class);

			// MarkupContainer row for remember me checkbox
			final WebMarkupContainer rememberMeRow = new WebMarkupContainer("rememberMeRow");
			add(rememberMeRow);

			// Add rememberMe checkbox
			rememberMeRow.add(new CheckBox("rememberMe", new PropertyModel<Boolean>(LoginPanel.this, "rememberMe")));

			// Make form values persistent
			setPersistent(rememberMe);

			// Show remember me checkbox?
			rememberMeRow.setVisible(includeRememberMe);
			
			add(new Image("submit", IconFactory.createOkIconReference()));
			
			Link<Void> signUpLink = new Link<Void>("signupButton") {
				@Override
				public void onClick() {
					getRequestCycle().setRequestTarget(new RedirectRequestTarget("/signup.html"));
				}
			};
			signUpLink.add(new Image("icon", IconFactory.createInformationIconReference()));
			add(signUpLink);
		}

		/**
		 * @see org.apache.wicket.markup.html.form.Form#onSubmit()
		 */
		@Override
		public final void onSubmit() {
	        ChigsWebSession session = (ChigsWebSession) ChigsWebSession.get();
	        if(session.signIn(getEmail(), getPassword())) {
	        	onSignInSucceeded();
	        } else {
	        	onSignInFailed();
	        }
		}
	}
}
